
/**
 * AppleIIGo
 * Videoterm class
 * (C) 2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#include "Videoterm.h"

UINT8 videotermRegisterInit[VIDEOTERM_END] = {
	0x7b, 0x50, 0x62, 0x29, 0x1b, 0x08, 0x18, 0x19,
	0x00, 0x08, 0xc0, 0x08, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00
};

Videoterm::Videoterm(Motherboard * motherboard, char * slotDeviceName) :
SlotDevice(motherboard, slotDeviceName) {
}

void Videoterm::onDevicesConnected() {
	SlotDevice::onDevicesConnected();
	motherboard->getIou()->connectAn0ToVideoterm(true);
}

void Videoterm::onMemoryRequested() {
	romMemoryOffset =
		motherboard->getMemory()->requestMemory(VIDEOTERM_ROM_BYTENUM);
}

void Videoterm::onMemoryAllocated() {
	romMemory = motherboard->getMemory()->getMemory(romMemoryOffset);
	shadowMemory = motherboard->getMemory()->getShadowMemory();
	char * romImage = "Videx Videoterm ROM 2.4.bin";
	motherboard->getResources()->readResource(romMemory, 
											  VIDEOTERM_ROM_BYTENUM,
											  romImage);
}

void Videoterm::onResetAsserted(bool isRestart) {
	if (!isRestart)
		return;
	
	videotermRegisterIndex = 0;
	
	for (UINT32 index = 0; index < VIDEOTERM_END; index++)
		videotermRegister[index] = videotermRegisterInit[index];
	
	setBankRegister(0);
}

void Videoterm::writeIo(UINT16 address, UINT8 value) {
	setBankRegister((address >> 2) & 0x3);
	
	if (address & 0x1)
		videotermRegister[videotermRegisterIndex] = value;
	else
		videotermRegisterIndex =
			(value >= VIDEOTERM_END) ? VIDEOTERM_INVALID : value;
}

UINT8 Videoterm::readIo(UINT16 address) {
	setBankRegister((address >> 2) & 0x3);
	
	return videotermRegister[videotermRegisterIndex];
}

void Videoterm::writeMemory(UINT16 address, UINT8 value) {
	if ((address & 0xc00) == 0xc00)
		shadowMemory[shadowMemoryOffset + (address & 0x1ff)] = value;
}

UINT8 Videoterm::readMemory(UINT16 address) {
	if ((address & 0xc00) == 0xc00)
		return shadowMemory[shadowMemoryOffset + (address & 0x1ff)];
	else
		return romMemory[address & 0x3ff];
}

void Videoterm::setBankRegister(UINT8 value) {
	bankRegister = value;
	shadowMemoryOffset = SHADOWMEMORY_VIDEOTERM + bankRegister * 0x200;
}
